import { useDebounceFn, useMemoizedFn, useRequest } from 'ahooks';
import { Rate as AntdRate, message, Popover, Tag as AntdTag, Tooltip } from 'antd';
import { rateV1ControllerBatchShow, rateV1ControllerShowByLogin, rateV1ControllerRating } from '@/services/auto/pingfen';
import { useModel } from '@umijs/max';
import NP from 'number-precision';
import { openLoginModal } from './LoginModal';
import { PropsWithChildren, useState, createContext, useEffect, useRef, useMemo, useContext } from 'react';
import cs from 'classnames';

function Rate({
    bizUuid,
    className,
}: {
    bizUuid: string;
    className?: string;
}) {

    const { data: userData } = useModel('user', ({ data }) => ({
        data: data,
    }));

    const [userScore, setUserScore] = useState(0);

    const {
        data: rateData,
        refresh: refreshRateData,
    } = useRequest(userData ? () => rateV1ControllerShowByLogin({
        bizUuid,
    }) : () => rateV1ControllerBatchShow({
        bizUuidList: bizUuid,
    }).then(res => res[0]), {
        refreshDeps: [bizUuid, userData],
        onSuccess: (res) => {
            // @ts-ignore
            if (res.currentUserScore !== null) {
                // @ts-ignore
                setUserScore(NP.strip(res.currentUserScore / 20));
            } else {
                setUserScore(0);
            }
        }
    })

    const {
        runAsync: handleRate,
    } = useRequest(rateV1ControllerRating, {
        manual: true,
        onSuccess: () => {
            message.success('评价成功');
            refreshRateData();
        },
    })

    return <div className={cs('inline-flex items-center h-[32px]', className)}>
        {
            <span className='flex items-center'>
                {
                    (rateData?.averageScore !== null && rateData?.averageScore !== undefined) ? <span className='flex items-center gap-[8px]'>
                        <span className='bold text-[20px]'>{rateData ? (rateData.averageScore / 10).toFixed(1) : 0}</span>
                        <AntdRate value={rateData ? rateData?.averageScore / 20 : 0} disabled />
                        <span>{rateData?.userCount ?? 0}人评价</span>
                    </span> : <span>暂无人评价</span>
                }
                <span>，</span>
            </span>
        }
        {
            userData ? <Popover trigger="click" content={
                <AntdRate allowHalf value={userScore} onChange={(val) => {
                    setUserScore(val);
                    handleRate({
                        bizUuid,
                        score: NP.strip(val * 20),
                    });
                }} />
            }>
                <a onClick={(e) => {
                    e.stopPropagation();
                }}>{userScore ? '点击修改评价' : '点击评价'}</a>
            </Popover> :
                <a onClick={(e) => {
                    e.stopPropagation();
                    openLoginModal();
                }}>登录后评价</a>
        }
    </div>
}

const RateTagContext = createContext<{
    add: (bizUuid: string) => void;
    // remove: (bizUuid: string)=>void
    rateMap: RateMap
}>({
    add: () => { },
    // remove: ()=>{},
    rateMap: {},
});

function RateTagProvider({
    children
}: PropsWithChildren) {
    const [rateMap, setRateMap] = useState<RateMap>({});

    const tempBizUuidListRef = useRef<string[]>([]);

    const {
        runAsync: batchShow,
    } = useRequest(rateV1ControllerBatchShow, {
        manual: true,
        onSuccess: (res) => {
            const obj: RateMap = {};
            res.forEach(item => {
                obj[item.bizUuid] = {
                    averageScore: item.averageScore,
                    userCount: item.userCount,
                }
            })
            setRateMap(origin => {
                return {
                    ...origin,
                    ...obj,
                }
            })
        },
    })

    const {run: batchShowDeb} = useDebounceFn(()=>{
        const bizUuidList = tempBizUuidListRef.current.join(',');
        tempBizUuidListRef.current = [];
        batchShow({bizUuidList});
    },{
        wait: 300,
    })

    const add = useMemoizedFn((bizUuid: string) => {
        tempBizUuidListRef.current.push(bizUuid);
        batchShowDeb();
    })

    const value = useMemo(() => {
        return {
            add,
            rateMap,
        }
    }, [rateMap])


    return <RateTagContext.Provider value={value}>
        {children}
    </RateTagContext.Provider>
}

function RateTag({
    bizUuid,
    className,
}: {
    bizUuid: string;
    className?: string;
}) {
    const {add, rateMap} = useContext(RateTagContext)

    useEffect(()=>{
        add(bizUuid);
    },[])

    const data = rateMap[bizUuid];

    if(!data){
        return <></>;
    }

    return <Tooltip title={`${data.userCount}人评价`}>
        <AntdTag className={className} bordered={false} color="gold">{(data.averageScore / 10).toFixed(1)}</AntdTag>
    </Tooltip>
}

Rate.Tag = RateTag;
Rate.TagProvider = RateTagProvider;

export default Rate;

type RateMap = Record<string, Omit<API.RateShowResult, 'bizUuid'>>;